#include "log.h"
#include <map>
#include <functional>
#include "config.h"
#include"util.h"

namespace yuechuan {
    const char *LogLevel::toString(LogLevel::Level level) {
        switch (level) {
#define XX(name)         \
    case LogLevel::name: \
        return #name;    \
        break;

            XX(DEBUG);
            XX(ERROR);
            XX(WARN);
            XX(INFO);
            XX(FATAL);
#undef XX
            default:
                return "UNKNOW";
        }
    }

    LogLevel::Level LogLevel::FromString(const std::string &str) {
#define XX(name)               \
    if (str == #name)          \
    {                          \
        return LogLevel::name; \
    }

        XX(DEBUG);
        XX(ERROR);
        XX(WARN);
        XX(INFO);
        XX(FATAL);
        return LogLevel::UNKNOW;
#undef XX
    }

    LogEventWrap::LogEventWrap(LogEvent::ptr e) : m_event(e) {
    }

    std::stringstream &LogEventWrap::getSS() {
        return m_event->getSS();
    }

    LogEventWrap::~LogEventWrap() {
        m_event->getLogger()->log(m_event->getLevel(), m_event);
    }

    // FormatItem 对象 创建开始  分别将事件的content,threadId,fiberId,elapse,time,fileName 以及log的等级名称------------

    /**
     * @brief 正文消息对象
     */
    class MessageFormatItem : public LogFormatter::FormatItem {
    public:
        MessageFormatItem(const std::string &str = "") {}

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level leve, LogEvent::ptr event) override {
            os << event->getContent();
        }
    };

    /**
     * @brief 日志等级对象
     */
    class LevelFormatItem : public LogFormatter::FormatItem {
    public:
        LevelFormatItem(const std::string &str = "") {}

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << LogLevel::toString(level);
        }
    };

    /**
     * @brief 日志器对象
     */
    class LoggerFormatItem : public LogFormatter::FormatItem {
    public:
        LoggerFormatItem(const std::string &str = "") {}

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << logger->getName();
        }
    };

    /**
     * @brief 线程ID对象
     */
    class ThreadIdFormatItem : public LogFormatter::FormatItem {
    public:
        ThreadIdFormatItem(const std::string &str = "") {}

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << event->getThreadId();
        }
    };

    /**
     * @brief 协程ID对象
     */
    class FiberIdFormatItem : public LogFormatter::FormatItem {
    public:
        FiberIdFormatItem(const std::string &str = "") {}

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << event->getFiberId();
        }
    };

    /**
     * @brief 线程名称对象
     */
    class ThreadNameFormatItem : public LogFormatter::FormatItem {
    public:
        ThreadNameFormatItem(const std::string &str = "") {}

        void format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) {
            os << event->getThreadName();
        }
    };

    /**
     * @brief 程序运行时间对象
     */
    class ElapseFormatItem : public LoggerFormatItem::FormatItem {
    public:
        ElapseFormatItem(const std::string &str = "") {}

        void format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) {
            os << event->getElapse();
        }
    };

    /**
     * @brief 日志器名称对象
     */
    class NameFormatItem : public LogFormatter::FormatItem {
    public:
        NameFormatItem(const std::string &str = "") {}

        void format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) {
            os << event->getLogger()->getName();
        }
    };

    /**
     * @brief 日志触发时间对象
     */
    class DateTimeFormatItem : public LogFormatter::FormatItem {
    public:
        DateTimeFormatItem(const std::string &format = "%Y-%m-%d %H:%M:%S")
                : m_format(format) {
            if (m_format.empty()) {
                m_format = "%Y-%m-%d %H:%M:%S";
            }
        }

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) override {
            struct tm tm;
            time_t time = event->getTime();
            localtime_r(&time, &tm);
            char buf[64];
            strftime(buf, sizeof(buf), m_format.c_str(), &tm);
            os << buf;
        }

    private:
        std::string m_format;
    };

    /**
     * @brief 文件名称对象
     */
    class FilenameFormatItem : public LogFormatter::FormatItem {
    public:
        FilenameFormatItem(const std::string &str = "") {}

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << event->getFile();
        }
    };

    /**
     * @brief 插入新字符对象
     */
    class StringFormatItem : public LoggerFormatItem::FormatItem {
    public:
        StringFormatItem(const std::string &str = "") : m_string(str) {}

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << m_string;
        }

    private:
        std::string m_string;
    };

    /**
     * @brief \t 对象
     */
    class TabFormatItem : public LoggerFormatItem::FormatItem {
    public:
        TabFormatItem(const std::string &str = "") {}

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << "\t";
        }
    };

    /**
     * @brief 新创建行对象
     */
    class NewLineFormatItem : public LoggerFormatItem::FormatItem {
    public:
        NewLineFormatItem(const std::string &str = "") {}

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << std::endl;
        }
    };

    /**
     * @brief 触发日志的事件在文件中函数对象
     */
    class LineFormatItem : public LogFormatter::FormatItem {
    public:
        LineFormatItem(const std::string &str = "") {}

        void
        format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) override {
            os << event->getLine();
        }
    };

    // FormatItem 创建结束 End ------------------------

    Logger::Logger(const std::string &name)
            : m_name(name), m_level(LogLevel::DEBUG) {
        m_formatter.reset(new LogFormatter("%d{%Y-%m-%d %H:%M:%S}%T%t%T%N%T%F%T[%p]%T[%c]%T%f:%l%T%m%n")); // 默认的输出格式
    }

    void Logger::log(LogLevel::Level level, LogEvent::ptr event) {
        if (level >= m_level) {
            auto self = shared_from_this();
            MutexType::Lock lock(m_mutex);
            if (!m_appenders.empty()) {
                for (auto &i : m_appenders) {
                    i->log(self, level, event);
                }
            } else if (m_root) {
                m_root->log(level, event);
            }
        }
    }

    void Logger::debug(LogEvent::ptr event) {
        log(LogLevel::DEBUG, event);
    }

    void Logger::info(LogEvent::ptr event) {
        log(LogLevel::INFO, event);
    }

    void Logger::warn(LogEvent::ptr event) {
        log(LogLevel::WARN, event);
    }

    void Logger::error(LogEvent::ptr event) {
        log(LogLevel::ERROR, event);
    }

    void Logger::fatal(LogEvent::ptr event) {
        log(LogLevel::FATAL, event);
    }


    void Logger::addAppender(LogAppender::ptr appender) {
        MutexType::Lock lock(m_mutex);
        if (!appender->getLogFormatter()) {
            MutexType::Lock ll(appender->m_mutex);
            appender->m_formatter = m_formatter;
        }
        m_appenders.push_back(appender);
    }

    void Logger::delAppender(LogAppender::ptr appender) {
        MutexType::Lock lock(m_mutex);
        for (auto it = m_appenders.begin(); it != m_appenders.end(); ++it) {
            if (*it == appender) {
                m_appenders.erase(it);
                break;
            }
        }
    }

    void Logger::clearAppender() {
        MutexType::Lock lock(m_mutex);
        m_appenders.clear();
    }

    void Logger::setLogFormatter(const LogFormatter::ptr &formatter) {
        MutexType::Lock lock(m_mutex);
        m_formatter = formatter;
        for (auto &i : m_appenders) {
            /// 在LogAppender中也会有用到锁的操作，所以这里需要加锁
            MutexType::Lock ll(i->m_mutex);
            if (!i->m_hasFormatter) {
                i->m_formatter = m_formatter;
            }
        }
    }

    void Logger::setLogFormatter(const std::string &format) {
        LogFormatter::ptr new_format(new LogFormatter(format));
        if (new_format->isError()) {
            std::cout << "Formatter Error name= " << m_name << " value = " << format << std::endl;
            return;
        }
        setLogFormatter(new_format);
    }

    std::string Logger::toYamlString() {
        MutexType::Lock lock(m_mutex);
        YAML::Node node;
        node["name"] = m_name;
        if (m_level != LogLevel::UNKNOW) {
            node["level"] = LogLevel::toString(m_level);
        }
        if (m_formatter) {
            node["formatter"] = m_formatter->getPattern();
        }

        for (auto &i : m_appenders) {
            node["appenders"].push_back(YAML::Load(i->toYamlString()));
        }
        std::stringstream ss;
        ss << node;
        return ss.str();
    }

    LogEvent::LogEvent(std::shared_ptr<Logger> logger, LogLevel::Level level, const char *file,
                       int32_t line, uint32_t elapse, uint32_t thread_id, uint32_t fiber_id,
                       uint64_t time, std::string threadName)
            : m_file(file),
              m_line(line),
              m_elapse(elapse),
              m_threadId(thread_id),
              m_fiberId(fiber_id),
              m_time(time),
              m_logger(logger),
              m_level(level),
              m_threadName(threadName) {}

    void LogEvent::format(const char *fmt, ...) {
        va_list al;
        va_start(al, fmt);
        format(fmt, al);
        va_end(al);
    }

    void LogEvent::format(const char *fmt, va_list al) {
        char *buf = nullptr;
        int len = vasprintf(&buf, fmt, al);
        if (len != -1) {
            m_ss << std::string(buf, len);
            free(buf);
        }
    }

    LogFormatter::ptr LogAppender::getLogFormatter() {
        MutexType::Lock lock(m_mutex);
        return m_formatter;
    }

    void LogAppender::setLogFormatter(LogFormatter::ptr format) {
        MutexType::Lock lock(m_mutex);
        m_formatter = format;
        if (m_formatter) {
            m_hasFormatter = true;
        } else {
            m_hasFormatter = false;
        }
    }

    FileLogAppender::FileLogAppender(const std::string &fileName)
            : m_filename(fileName) {
        reopen();
    }

    void FileLogAppender::log(std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) {
        if (level >= m_level) {
            /**
             * @brief 解决文件删除感知问题
             * @detials 在程序执行过程中，当日志写入文件删除时，是无法感知的，即不会终止，不会有提示
             *          所以在程序执行一段时间后就要重新尝试打开文件，来判断文件是否被删除，从而进行感知
             */
            uint64_t now = event->getTime();
            if (now >= (m_lastTime + 3)) {
                reopen();
                m_lastTime = now;
            }
            MutexType::Lock lock(m_mutex);
            if (!m_formatter->format(m_fileOstream, logger, level, event)) {
                std::cout << "error" << std::endl;
            } /// 将经过formatItem转换后的字符串写到文件流中；
        }
    }

    std::string FileLogAppender::toYamlString() {
        MutexType::Lock lock(m_mutex);
        YAML::Node node;
        node["type"] = "FileLogAppender";
        node["file"] = m_filename;
        if (m_level != LogLevel::UNKNOW) {
            node["level"] = LogLevel::toString(m_level);
        }
        if (m_hasFormatter && m_formatter) {
            node["formatter"] = m_formatter->getPattern();
        }
        std::stringstream ss;
        ss << node;
        return ss.str();
    }

    bool FileLogAppender::reopen() {
        /// 判断流是否已经存在，如果存在就将其进行关闭，然后在根据对象的filename进行重新打开，并返回ture
        MutexType::Lock lock(m_mutex);
        if (m_fileOstream) {
            m_fileOstream.close();
        }
        return FSUtil::OpenForWrite(m_fileOstream, m_filename, std::ios::app);
    }

    void StdoutLogAppender::log(std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) {
        if (level >= m_level) {
            MutexType::Lock lock(m_mutex);
            m_formatter->format(std::cout, logger, level, event); // 将经过formattem转换后的字符串写到控制台中；
        }
    }

    std::string StdoutLogAppender::toYamlString() {
        MutexType::Lock lock(m_mutex);
        YAML::Node node;
        node["type"] = "StdoutLogAppender";
        if (m_level != LogLevel::UNKNOW) {
            node["level"] = LogLevel::toString(m_level);
        }
        if (m_hasFormatter && m_formatter) {
            node["formatter"] = m_formatter->getPattern();
        }
        std::stringstream ss;
        ss << node;
        return ss.str();
    }

    LogFormatter::LogFormatter(const std::string &pattern)
            : m_pattern(pattern) {
        init();
    }

    std::string LogFormatter::format(std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) {
        std::stringstream ss;
        for (auto &i : m_items) {
            i->format(ss, logger, level, event);
        }

        return ss.str();
    }

    std::ostream &
    LogFormatter::format(std::ostream &os, std::shared_ptr<Logger> logger, LogLevel::Level level, LogEvent::ptr event) {
        for (auto &i: m_items) {
            i->format(os, logger, level, event);
        }
        return os;
    }

    /// 对m_pattern进行解析
    void LogFormatter::init() {
        std::vector<std::tuple<std::string, std::string, int>> vec;
        std::string nstr;
        for (size_t i = 0; i < m_pattern.size(); ++i) {
            if (m_pattern[i] != '%') {
                nstr.append(1, m_pattern[i]);
                continue;
            }

            if ((i + 1) < m_pattern.size()) {
                if (m_pattern[i + 1] == '%') {
                    nstr.append(1, '%');
                    continue;
                }
            }

            size_t n = i + 1;
            int fmt_status = 0;
            size_t fmt_begin = 0;

            std::string str;
            std::string fmt;
            while (n < m_pattern.size()) {
                if (!fmt_status && (!isalpha(m_pattern[n]) && m_pattern[n] != '{' && m_pattern[n] != '}')) {
                    str = m_pattern.substr(i + 1, n - i - 1);
                    break;
                }
                if (fmt_status == 0) {
                    if (m_pattern[n] == '{') {
                        str = m_pattern.substr(i + 1, n - i - 1);
                        // std::cout << "*" << str << std::endl;
                        fmt_status = 1; //解析格式
                        fmt_begin = n;
                        ++n;
                        continue;
                    }
                } else if (fmt_status == 1) {
                    if (m_pattern[n] == '}') {
                        fmt = m_pattern.substr(fmt_begin + 1, n - fmt_begin - 1);
                        fmt_status = 0;
                        ++n;
                        break;
                    }
                }
                ++n;
                if (n == m_pattern.size()) {
                    if (str.empty()) {
                        str = m_pattern.substr(i + 1);
                    }
                }
            }

            if (fmt_status == 0) {
                if (!nstr.empty()) {
                    vec.push_back(std::make_tuple(nstr, std::string(), 0));
                    nstr.clear();
                }
                vec.push_back(std::make_tuple(str, fmt, 1));
                i = n - 1;
            } else if (fmt_status == 1) {
                std::cout << "pattern parse error: " << m_pattern << " - " << m_pattern.substr(i) << std::endl;
                m_error = true;
                vec.push_back(std::make_tuple("<<pattern_error>>", fmt, 0));
            }
        }

        if (!nstr.empty()) {
            vec.push_back(std::make_tuple(nstr, "", 0));
        }
        static std::map<std::string, std::function<FormatItem::ptr(const std::string &str)>> s_format_items = {
#define XX(str, C)                                                               \
    {                                                                            \
#str, [](const std::string &fmt) { return FormatItem::ptr(new C(fmt)); } \
    }
                //{"m", [](const std::string& fmt) { return FormatItem::ptr( new MessageFormatItem(fmt));}}
                XX(m, MessageFormatItem),               /// m: 消息
                XX(p, LevelFormatItem),                 /// p: 日志级别
                XX(r, ElapseFormatItem),                /// r: 累计秒数
                XX(c, NameFormatItem),                  /// c: 日志名称
                XX(t, ThreadIdFormatItem),              /// t: 线程ID
                XX(n, NewLineFormatItem),               /// n: 换行
                XX(d, DateTimeFormatItem),              /// d: 时间
                XX(f, FilenameFormatItem),              /// f: 文件名称
                XX(l, LineFormatItem),                  /// l: 行号
                XX(F, FiberIdFormatItem),               /// F: 协程ID
                XX(T, TabFormatItem),                   /// T: Tab
                XX(N, ThreadNameFormatItem)             /// N: 线程名称
#undef XX
        };
        for (auto &i : vec) {
            if (std::get<2>(i) == 0) {
                m_items.push_back(FormatItem::ptr(new StringFormatItem(std::get<0>(i))));
            } else {
                auto it = s_format_items.find(std::get<0>(i));
                if (it == s_format_items.end()) {
                    m_items.push_back(
                            FormatItem::ptr(new StringFormatItem("<< error_format %" + std::get<0>(i) + ">>")));
                    m_error = true;
                } else {
                    m_items.push_back(it->second(std::get<1>(i)));
                }
            }
        }
    }

    LoggerManager::LoggerManager() {
        m_root.reset(new Logger);
        m_root->addAppender(LogAppender::ptr(new StdoutLogAppender));
        m_logger[m_root->m_name] = m_root;

        init();
    }

    Logger::ptr LoggerManager::getLogger(const std::string &name) {
        MutexType::Lock lock(m_mutex);
        auto it = m_logger.find(name);
        if (it != m_logger.end()) {
            return it->second;
        }
        Logger::ptr logger(new Logger(name));
        logger->m_root = m_root;
        m_logger[name] = logger;
        return logger;
    }

    /**
     * @brief 日志配置定义
     * @details 目的是实现从yaml文件中读取，将配置直接转换为log的配置
     *          该类是定义日志在配置文件中相关属性的定义
     */
    struct LogAppenderDefine {
        int type = 0;           /// 1->file 2->Std
        LogLevel::Level level = LogLevel::Level::UNKNOW;
        std::string formatter;
        std::string file;

        bool operator==(const LogAppenderDefine &other) const {
            return type == other.type
                   && level == other.level
                   && file == other.file
                   && formatter == other.formatter;
        }
    };

    /**
     * @brief 日志对象定义，方便从yaml文件中读取然后直接转换为日志
     */
    struct LogDefine {
        std::string name;
        LogLevel::Level level = LogLevel::UNKNOW;
        std::string formatter;
        std::vector<LogAppenderDefine> appenders;

        bool operator==(const LogDefine &other) const {
            return name == other.name
                   && level == other.level
                   && formatter == other.formatter
                   && appenders == other.appenders;
        }

        bool operator<(const LogDefine &other) const {
            return name < other.name;
        }
    };

    /**
     * @brief 将string类型转换为日志配置类型，偏特化
     */
    template<>
    class LexicalCast<std::string, LogDefine> {
    public:
        LogDefine operator()(const std::string &str) {
            YAML::Node n = YAML::Load(str);
            LogDefine ld;
            if (!n["name"].IsDefined()) {
                std::cout << "log config error: name is null, " << n
                          << std::endl;
                throw std::logic_error("log config name is null");
            }
            ld.name = n["name"].as<std::string>();
            ld.level = LogLevel::FromString(n["level"].IsDefined() ? n["level"].as<std::string>() : "");
            if (n["formatter"].IsDefined()) {
                ld.formatter = n["formatter"].as<std::string>();
            }

            if (n["appenders"].IsDefined()) {
                for (size_t x = 0; x < n["appenders"].size(); ++x) {
                    auto a = n["appenders"][x];
                    if (!a["type"].IsDefined()) {
                        std::cout << "log config error: appender type is null, " << a
                                  << std::endl;
                        continue;
                    }
                    std::string type = a["type"].as<std::string>();
                    LogAppenderDefine lad;
                    if (type == "FileLogAppender") {
                        lad.type = 1;
                        if (!a["file"].IsDefined()) {
                            std::cout << "log config error: fileappender file is null, " << a
                                      << std::endl;
                            continue;
                        }
                        lad.file = a["file"].as<std::string>();
                        if (a["formatter"].IsDefined()) {
                            lad.formatter = a["formatter"].as<std::string>();
                        }
                    } else if (type == "StdoutLogAppender") {
                        lad.type = 2;
                        if (a["formatter"].IsDefined()) {
                            lad.formatter = a["formatter"].as<std::string>();
                        }
                    } else {
                        std::cout << "log config error: appender type is invalid, " << a
                                  << std::endl;
                        continue;
                    }

                    ld.appenders.push_back(lad);
                }
            }
            return ld;
        }
    };

    /**
     * @brief 将日志配置类型转换为字符串类型, 偏特化
     */
    template<>
    class LexicalCast<LogDefine, std::string> {
    public:
        std::string operator()(const LogDefine &def) {
            YAML::Node n;
            n["name"] = def.name;
            if (def.level != LogLevel::UNKNOW) {
                n["level"] = LogLevel::toString(def.level);
            }
            if (!def.formatter.empty()) {
                n["formatter"] = def.formatter;
            }

            for (auto &a : def.appenders) {
                YAML::Node na;
                if (a.type == 1) {
                    na["type"] = "FileLogAppender";
                    na["file"] = a.file;
                } else if (a.type == 2) {
                    na["type"] = "StdoutLogAppender";
                }
                if (a.level != LogLevel::UNKNOW) {
                    na["level"] = LogLevel::toString(a.level);
                }

                if (!a.formatter.empty()) {
                    na["formatter"] = a.formatter;
                }

                n["appenders"].push_back(na);
            }
            std::stringstream ss;
            ss << n;
            return ss.str();
        }
    };

    /**
     * @brief 日志初始化类
     * @details 为了实现在main函数之前就对log进行初始化，可以创建一个全局变量，在该变量的构造函数中执行要进行的操作
     */
    struct LogIniter {
        LogIniter() {
            yuechuan::ConfigVar<std::set<LogDefine>>::ptr log_define = yuechuan::Config::Lookup("logs",
                                                                                                std::set<LogDefine>(),
                                                                                                "logs config");

            log_define->addListener([](const std::set<LogDefine> &old_value, const std::set<LogDefine> &new_value) {
                YUECHUAN_LOG_INFO(YUECHUAN_LOG_ROOT()) << "on_logger_conf_changed";
                for (auto &i : new_value) {
                    auto it = old_value.find(i);
                    yuechuan::Logger::ptr logger;
                    if (it == old_value.end()) {
                        //新增logger
                        logger = YUECHUAN_LOG_NAME(i.name);
                    } else {
                        if (!(i == *it)) {
                            //修改的logger
                            logger = YUECHUAN_LOG_NAME(i.name);
                        } else {
                            continue;
                        }
                    }
                    logger->setLevel(i.level);
                    if (!i.formatter.empty()) {
                        logger->setLogFormatter(i.formatter);
                    }

                    logger->clearAppender();
                    for (auto &a : i.appenders) {
                        yuechuan::LogAppender::ptr ap;
                        if (a.type == 1) {
                            ap.reset(new FileLogAppender(a.file));
                        } else if (a.type == 2) {
                            ap.reset(new StdoutLogAppender);
                        }
                        ap->setLevel(a.level);
                        if (!a.formatter.empty()) {
                            LogFormatter::ptr fmt(new LogFormatter(a.formatter));
                            if (!fmt->isError()) {
                                ap->setLogFormatter(fmt);
                            } else {
                                std::cout << "log.name=" << i.name << " appender type=" << a.type
                                          << " formatter=" << a.formatter << " is invalid" << std::endl;
                            }
                        }
                        logger->addAppender(ap);
                    }
                }

                for (auto &i : old_value) {
                    auto it = new_value.find(i);
                    if (it == new_value.end()) {
                        //删除logger
                        auto logger = YUECHUAN_LOG_NAME(i.name);
                        logger->setLevel((LogLevel::Level) 0);
                        logger->clearAppender();
                    }
                }
            });
        }
    };

    static LogIniter __log_init;

    std::string LoggerManager::toYamlString() {
        MutexType::Lock lock(m_mutex);
        YAML::Node node;
        for (auto &i : m_logger) {
            node.push_back(YAML::Load(i.second->toYamlString()));
        }
        std::stringstream ss;
        ss << node;
        return ss.str();
    }

    /// LoggerManager的初始化操作，默认输出地为控制台
    void LoggerManager::init() {
        m_root.reset(new Logger);
        m_root->addAppender(LogAppender::ptr(new StdoutLogAppender));

        m_logger[m_root->m_name] = m_root;
    }

} // namespace yuechuan
